package com.反射Reflection.Reflection___;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStreamReader;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Properties;
@SuppressWarnings("all")
public class reflection的使用 {
    /**这是要反射的类的结构
     * public class ww {
     *     String name = "jack";
     *     private int age = 18;
     *     public ww(){
     *         System.out.println("无参构造器  ww()");
     *     }
     *     public ww(String s){
     *         System.out.println("有参构造器  ww(String s)");
     *     }
     *     public static void main(String[] args) throws IOException { System.out.println("反射 main(String[] args)"); }
     *     public void hi(){  System.out.println("反射 hi()");  }
     * }

     */

    public static void main(String[] args) throws Exception {
        Properties properties = new Properties();
        properties.load(new InputStreamReader(new FileInputStream("java-code/src/com/反射Reflection/引出反射/class.properties")));
        /// 读取字符串保存到信息
        String classFullPath = properties.getProperty("ClassFullPath");
        String method = properties.getProperty("method");

        /// 加载类 并 反射获取 方法和成员变量，构造器
        Class<?> cls = Class.forName(classFullPath);  ///加载类；
        Object reflectionClass = cls.newInstance();   ///创建类对象  这里会调用一次无参构造器
        Constructor<?> constructor1 = cls.getConstructor();               ///得到无参构造器；
        Constructor<?> constructor2 = cls.getConstructor(String.class);   ///得到有参构造器；带String形参的
        Method main = cls.getMethod("main", String[].class);        ///得到名字叫main，形参类型是String[]的方法
        Method hi = cls.getMethod("hi");               ///得到名字叫hi的无参方法
///     Field ageField = cls.getField("age");                这些方法通过反射获取私有属性时会报错；
        Field nameFiled = cls.getField("name");        ///得到名字叫name的变量

        /// 调用 方法和变量
        /// 方法的调用是 方法对象.invoke( 反射得到的类 )
        /// 属性的获取值是 属性变量对象.get( 反射得到的类 )
        String[] str = new String[0];                        ///你需要在调用 main 方法时指定传入一个 String[] 参数，
        main.invoke(reflectionClass,(Object) str);          ///调用main方法，这里形参要强制转型为 (Object)，否则会触发 invoke 的参数展开机制，导致误认为你传入的是多个参数（而不是一个数组）。
        hi.invoke(reflectionClass);                         ///调用无参hi、方法
        System.out.println(nameFiled.get(reflectionClass)); ///得到属性对象的值；

        /// 调用构造器创建对象
        Object o1 = constructor1.newInstance(); ///用反射来的无参构造器来创建对象
        System.out.println(constructor1);       ///输出构造器的类型 public WW()
        Object o2 = constructor2.newInstance("gg"); ///用反射来的有参构造器来创建对象
        System.out.println(constructor2);       ///输出构造器的类型 public WW(java.lang.String)


    }
}
